﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace GameBasic.Editors
{
    [CustomPropertyDrawer(typeof(EnumTextAttribute))]
    public class EnumTextAttributeDrawer : PropertyDrawer
    {
        static Dictionary<Type, Dictionary<string, int>> caches;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EnumTextAttribute attr = attribute as EnumTextAttribute;
            Type type = attr.type;
            SerializedProperty enumName = property.FindPropertyRelative("name");
            SerializedProperty enumValue = property.FindPropertyRelative("value");
            string name = enumName.stringValue;
            long value = enumValue.longValue;

            if (caches == null)
                caches = new ();
            if (!caches.TryGetValue(attr.type, out var dic))
            {
                var enumNames = Enum.GetNames(type);
                dic = new Dictionary<string, int>(enumNames.Length);
                caches[type] = dic;
                for (int i = 0, length = enumNames.Length; i < length; i++)
                {
                    string n = enumNames[i];
                    dic[n] = (int)Enum.Parse(type, n);
                }
            }

            // 名字, Value
            // n, y : name from value （重命名，fix name）
            // n, n : bug提示 （重命名，值也变了）
            // y, n : value from name （值变了，fix value）
            // y, y : 正常

            bool bug = false;

            if (dic.TryGetValue(name, out int v))
            {
                // fix value
                value = v;
            }
            // 无法匹配 name
            else
            {
                bool valueMatch = false;
                foreach (var item in dic)
                {
                    if (item.Value == value)
                    {
                        // fix name
                        name = item.Key;
                        valueMatch = true;
                        break;
                    }
                }
                bug = !valueMatch;
            }

            // Fix Button
            if (bug)
            {
                position.width -= 80;
                EditorGUI.LabelField(position, property.displayName, $"{name}: {value}");

                position.x = position.xMax;
                position.width = 80;
                if (GUI.Button(position, "Fix"))
                {
                    value = 0;
                    bug = false;
                }
            }

            // EnumPopop
            if (!bug)
            {
                Enum selected = (Enum)Enum.ToObject(attr.type, value);
                selected = EditorGUI.EnumPopup(position, property.displayName, selected);

                // 更新属性值
                name = selected.ToString();
                enumName.stringValue = selected.ToString();
                enumValue.intValue = Convert.ToInt32(selected);
            }
        }
    }
}